-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libexpr: make "or"-as-variable less bogus #11121
base: master
Are you sure you want to change the base?
Conversation
Truly horrifying behavior, but it does classify as a breaking change I would say unfortunately. |
e30ae3f
to
3b48920
Compare
src/libexpr/parser.y
Outdated
@@ -263,6 +262,9 @@ expr_simple | |||
else | |||
$$ = new ExprVar(CUR_POS, state->symbols.create($1)); | |||
} | |||
| /* Backwards compatibility: because Nixpkgs has a rarely used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| /* Backwards compatibility: because Nixpkgs has a rarely used | |
| /* Backwards compatibility: because Nixpkgs has a |
Not for Nix to judge. (was also in the existing text)
Is it truly breaking though? Does it change a non-error behavior into a different behavior? What would be a breaking change is to disallow If we choose to do this, it does close some other doors. So I think the only thing we're looking for is an example of a true breaking change. I can't think of one right now, but I think we could analyze the grammar to make sure? |
I am honor-bound to report that yes, it does: builtins.length (let or = 1; in [ (x: x) or ]) evaluates to 1 currently and 2 with this patch. I think it's extraordinarily unlikely that this will cause anyone any problems, but if one is inclined to hew absolutely to the letter of the law with no exceptions, this is a breaking language change. |
That is horrible and was surely never intended, but yes, we should be very careful about this kind of thing. |
Could we distinguish the broken cases from the sensible ones? |
I suppose another workaround is to allow specifically |
Yeah, this is 4 currently and an error with the patch: let or = 1; in (x: x * 2) (x: x + 1) or Here's a really cursed one: 2 currently and an error with the patch: let or = 1; in { a = 2; }.a or (x: x) or
As the above shows, it's not just list elements that are affected. But if you're asking whether we could detect uses of
This patch does enable that, but I'm not seeing how that alone (without any other grammar changes) would fix the current issues with bad parses. It would just enable users to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really a bug? For a long time parser developers of nix language were considering this is a feature of Nix language and maybe we shouldn't fix that feature. (Both nixd and nil can correctly deal with that strange precedence).
In my humble opinion, if this should be "fixed" maybe just mark OR_KW
a keyword. And just don't allow keyword used as variable names, that's straightforward way of many other languages. For backward compatibility, we could introduce a new Xp
options that disallow keywords like or
used as variable names, and waiting for migration. (We have already done that for "url-literals").
That weird or
production mainly used for backward compatibility. Then why should we introduce a new "breaking" change to break that compatibility?
Behavior that is both confusing and unintentional is not a feature. If we didn't have to support any expressions that use This is a ‘breaking’ change only for cases that are exceedingly unlikely to arise in code that wasn't specifically written to be a Nix brainteaser or parser test case. I agree that caution is merited even in such cases, but not so much caution that we're forever trapped with the mistakes of ten years ago. We should be able to fix things that are both confusing and unintentional; it reflects poorly on the project if we can't. |
The behavior is intentional I suppose, it even have some comments in
IIRC, |
Personally, I'd be ok doing this with a long deprecation cycle where we warn about the upcoming change for a couple of years.
I think the term is "legacy", and that is - in part - a good thing; almost as good as removing it responsibly. Very responsibly, because Nix promises to be reproducible, and that's an empty claim if it's hard to keep up with its changes, and especially changes in the language, which - in principle - we should have none of. |
Good enough for me! Which ‘this’, though—making |
This involves preserving the current behavior, and warning about the cases where the current behavior doesn't match the behavior we want.
This seems easier to implement, but also less valuable and potentially more disruptive. |
I'd say that if we can't find a Nixpkgs where this change matters for drvPaths, we fix this as a bug, rather than considering a breaking language change. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2024-08-28-nix-team-meeting-minutes-173/51302/1 |
The previous place where OR_KW was inserted into the grammar to allow expressions like "map or [...]" led to a number of weird outcomes. By moving it to expr_simple, expressions using "or" as a variable are now parsed consistently with the rest of the language. Conflicts are prevented by telling Bison that OR_KW has higher precedence than '.'.
3b48920
to
ab1f07e
Compare
The previous place where OR_KW was inserted into the grammar to allow expressions like "map or [...]" led to a number of weird outcomes. By moving it to expr_simple, expressions using "or" as a variable are now parsed consistently with the rest of the language. Conflicts are prevented by telling Bison that OR_KW has higher precedence than '.'.
Fixes #11118.
If this is a ‘breaking change’, then I'm going to have to describe the existing behavior in the language reference. I'm not looking forward to that, because the existing behavior is bonkers.
Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.